/****************************************************************/
/****************************************************************/
//全局图标
var Icon = {
							//空格
							blank : "blank.gif",
							//节点展开
							folderopen : "folderopen.gif",
							//节点回收
							folderclosed : "folderclosed.gif",
							//叶子节点
							leaf : "leaf.gif",
							//节点缩进图标
							Rminus : "Rminus.gif",
							Rplus : "Rplus.gif",
							minusbottom : "Lminus.gif",
							plusbottom : "Lplus.gif",
							minus : "minus.gif",
							plus : "plus.gif",
							join : "T.gif",
							joinbottom : "L.gif",
							line : "I.gif"
						}
//全局环境参数
var Parameter = { 
									//文件路径
									imagePath : "images/",
									//是否需要checkbox
									requiredCheckbox : true,
									//checkbox是否递归反映
									recursionCheckbox : false,
									//节点标签ID
									tagId : "id",
									//节点链接target
									target : "_self"
								}
//全局树节点存储数组对象

var _treeNodes = new Array();
//全局树节点checkbox选中状态
var	_selectedNodes = new Array();
//全局函数，通过节点id,得到节点对象
function _getNode(nodeId)
{
	return _treeNodes[nodeId];
}
//全局函数，设置指定节点为选中节点
function _selectNode(nodeId)
{
	//设置界面元素
	var checkboxElement = document.getElementById("checkbox_"+nodeId);
	checkboxElement.checked = true;
	//通过节点ID得到节点对象
	var selectedNode = _getNode(nodeId);
	//设置节点checked属性
	selectedNode.checked = true;
	//保存选中节点到数组中
	_selectedNodes[_selectedNodes.length] = selectedNode;
	//如果设置递归执行，选中节点的子节点需要同时选中
	if(Parameter.recursionCheckbox)
	{
		//执行向下
		_selectBlowNode(selectedNode);
		//执行向上
		_selectAboveNode(selectedNode);
	}
}
//全局函数，向上处理指定节点为选中节点
function _selectAboveNode(node)
{
	//得到当前节点的的父节点
	if(node==null || node.parentNodeId==null || node.parentNodeId<=0)
		return;
	var parentNode = _getNode(node.parentNodeId);
	/*
	//判断其兄弟节点是否都为选中状态 
	var totalChecked = true;
	for(var i=0;i<parentNode.childrenNodes.length;i++)
	{
		if(parentNode.childrenNodes[i].checked==false)
		{
			totalChecked = false;
			break;
		}
	}
	//如果都为选中状态，设置父节点也为选中状态，并递归执行到上一层
	if(totalChecked)
	{
	*/
		//保存选中节点到数组中
		_selectedNodes[_selectedNodes.length] = parentNode;
		//checkbox属性
		parentNode.checked = true;
		//设置界面元素
		var checkboxElement = document.getElementById("checkbox_"+parentNode.nodeId);
		checkboxElement.checked = true;
		//递归到上一层
		_selectAboveNode(parentNode);
	//}	
}
//全局函数，向下处理指定节点为选中节点
function _selectBlowNode(node)
{
	if(node==null)
		return;
	//得到当前节点的
	for(var i=0;i<node.childrenNodes.length;i++)
	{
		if(node.childrenNodes[i].checked==false)
		{
			//设置checkbox属性
			node.childrenNodes[i].checked = true;
			//保存选中节点到数组中
			_selectedNodes[_selectedNodes.length] = node.childrenNodes[i];
			//设置界面元素
			var checkboxElement = document.getElementById("checkbox_"+node.childrenNodes[i].nodeId);
			checkboxElement.checked = true;
			//递归执行
			_selectBlowNode(node.childrenNodes[i]);
		}
	}
}
//全局函数，设置取消指定节点选中状态
function _unselectNode(nodeId)
{
	//查找选中列表中，是否存在指定节点对象
	//如果存在删除，并从列表中去掉
	var finded = false;
	var selectedNode = null;
	for(var i=0;i<_selectedNodes.length;i++)
	{
		if(_selectedNodes[i].nodeId == nodeId)
		{
			//找到对象设置标志
			selectedNode = _selectedNodes[i];
			finded = true;
		}
		if(finded && i<(_selectedNodes.length-1))
			_selectedNodes[i] = _selectedNodes[i+1];
	}
	if(finded==true)
	{
		_selectedNodes.length = _selectedNodes.length - 1;
		//设置界面元素
		var checkboxElement = document.getElementById("checkbox_"+nodeId);
		checkboxElement.checked = false;
		//设置去除选择状态的节点属性
		selectedNode.checked = false;
		//向下执行递归
		_unselectBelowNode(selectedNode);
		//向上执行递归
		_unselectAboveNode(selectedNode);
	}
}
//全局函数，向上取消指定节点的父节点的选中状态
function _unselectAboveNode(node)
{
	if(node.parentNodeId!=null && node.parentNodeId>0)
	{
		var parentNode = _getNode(node.parentNodeId);
		/*
		//如果父节点也为选中状态，递归执行方法
		if(parentNode.checked==true)
		{
			var checkboxElement = document.getElementById("checkbox_"+parentNode.nodeId);
			checkboxElement.checked = false;
			parentNode.checked = false;
			_unselectArrayNode(parentNode);
			_unselectAboveNode(parentNode);
		}
		*/
		//判断其兄弟节点是否都为选中状态 
		var totalChecked = true;
		for(var i=0;i<parentNode.childrenNodes.length;i++)
		{
			if(parentNode.childrenNodes[i].checked==true)
			{
				totalChecked = false;
				break;
			}
		}
		//如果兄弟节点都没有被选中，设置父节点也为未选中状态，并递归执行到上一层
		if(totalChecked)
		{
			var checkboxElement = document.getElementById("checkbox_"+parentNode.nodeId);
			checkboxElement.checked = false;
			parentNode.checked = false;
			_unselectArrayNode(parentNode);
			_unselectAboveNode(parentNode);
		}
	}
}
//全局函数，向下取消指定节点的子节点的选中状态
function _unselectBelowNode(node)
{
	if(node==null)
		return;
	for(var i=0;i<node.childrenNodes.length;i++)
	{
		if(node.childrenNodes[i].checked==true)
		{
			var checkboxElement = document.getElementById("checkbox_"+node.childrenNodes[i].nodeId);
			checkboxElement.checked = false;
			node.childrenNodes[i].checked = false;
			_unselectArrayNode(node.childrenNodes[i]);
			_unselectBelowNode(node.childrenNodes[i]);		
		}
	}
}
//全局函数，设置从选中节点数组中去除指定节点
function _unselectArrayNode(node)
{
	var finded = false;
	for(var i=0;i<_selectedNodes.length;i++)
	{
		if(_selectedNodes[i].nodeId == node.nodeId)
			finded = true;
		if(finded && i<(_selectedNodes.length-1))
			_selectedNodes[i] = _selectedNodes[i+1];
	}
	if(finded==true)
		_selectedNodes.length = _selectedNodes.length - 1;
}
//全局函数,点击checkbox
function _selectCheckbox(nodeId)
{
	var checkboxElement = document.getElementById("checkbox_"+nodeId);
	//判断点击节点是否选中，并做不同处理
	if(checkboxElement.checked)
		_selectNode(nodeId);
	else
		_unselectNode(nodeId);			
}
//全局函数，点击显示子节点
function _openFolder(nodeId)
{
	var puckerElement = document.getElementById("pucker_"+nodeId);
	var folderElement = document.getElementById("folder_"+nodeId);
	var containerElement = document.getElementById("container_"+nodeId);
	var node = _treeNodes[eval(nodeId)];
	if(containerElement.style.display=="none")
	{
		folderElement.src = Parameter.imagePath+Icon.folderopen;
		if(puckerElement!=null)
		{
			//pucker展开显示策略
			if(node.parentNodeId==null || node.parentNodeId<0)
			{
				//根节点展开
				puckerElement.src = Parameter.imagePath+Icon.Rminus;
			}
			else 
			{
				//非根节点展开
				if(node.isLastSibling())
					puckerElement.src = Parameter.imagePath+Icon.minusbottom;
				else
					puckerElement.src = Parameter.imagePath+Icon.minus;
			}
		}
		containerElement.style.display="block";
	}
	else if(node.keepExpand==false)
	{
		//节点不为保持展开状态，回收处理
		folderElement.src = Parameter.imagePath+Icon.folderclosed;
		if(puckerElement!=null)
		{
			//pucker合拢显示策略
			if(node.parentNodeId==null || node.parentNodeId<0)
			{
				//根节点合拢

				puckerElement.src = Parameter.imagePath+Icon.Rplus;
			}
			else
			{
				//非根节点合拢
				if(node.isLastSibling())
					puckerElement.src = Parameter.imagePath+Icon.plusbottom;
				else
					puckerElement.src = Parameter.imagePath+Icon.plus;
			}
		}
		containerElement.style.display="none";
	}
}
/****************************************************************/
/****************************************************************/
//树对象

function Tree()
{
	//树根节点保存数组对象
	this.rootNodes = new Array();
}
//设置树展现图标位置

Tree.prototype.setImagePath = function(imagePath)
{
	//全局环境参数设置
	Parameter.imagePath = imagePath;
}
//设置树是否需要checkbox
Tree.prototype.setRequiredCheckbox = function(requiredCheckbox)
{
	//全局环境参数设置
	Parameter.requiredCheckbox = requiredCheckbox;
}
//设置树是否需要递归操作checkbox
Tree.prototype.setRecursionCheckbox = function(recursionCheckbox)
{
	//全局环境参数设置
	Parameter.recursionCheckbox = recursionCheckbox;
}
//设置树节点标签ID
Tree.prototype.setTagId = function(tagId)
{
	//全局环境参数设置
	Parameter.tagId = tagId;
}
//设置树节叶子节点链接target
Tree.prototype.setTarget = function(target)
{
	//全局环境参数设置
	Parameter.target = target;
}
//添加树节点方法

Tree.prototype.addNode = function(node)
{ 
	//首先把树节点保存到全局树节点数组对象中，并以节点id做索引

	_treeNodes[node.nodeId] = node;
	//设置节点的所属树对象属性

	node.tree = this;
	//兄弟节点列表对象
	var siblingNodes = null;
	//判断节点是否为根节点
	if(node.parentNodeId==null || node.parentNodeId<0)
	{
		//根节点

		siblingNodes = this.rootNodes;
	}
	else
	{ 
		//非根节点
		siblingNodes = _getNode(node.parentNodeId).childrenNodes;
	}
	//添加树节点到兄弟节点列表对象中

	if(node.nodeOrder==null || node.nodeOrder<0 || siblingNodes.length==0)
	{
		//如果节点次序为空、-1或者兄弟节点长度为0,设置节点添加到最后

		siblingNodes[siblingNodes.length] = node;
	}
	else
	{
		//次序有效，先后移动其后续节点，再插入新节点

		var location = siblingNodes.length-1;
		while(location >=0 &&
					(siblingNodes[location].nodeOrder==null ||
		 			 siblingNodes[location].nodeOrder<0 ||
		 			 siblingNodes[location].nodeOrder>node.nodeOrder))
		{
			siblingNodes[location+1] = siblingNodes[location];
			location--;
			//循环到头，插入到顶头
			if(location<0) break;
		}
		siblingNodes[location+1] = node;		
	}
}
//显示树方法

Tree.prototype.view = function()
{
	var htmlTree = "";
	for(var i=0;i<this.rootNodes.length;i++)
	{
		htmlTree += this.rootNodes[i].view();
	}
	document.write(htmlTree);
}
//设置树中指定节点一直保持展开状态

Tree.prototype.setKeepExpand = function(nodeId)
{
	//得到节点对象，并设置其为展开状态

	var node = _treeNodes[eval(nodeId)];
	node.keepExpand = true;
	//如果当前节点不是展开状态，展开该节点

	var containerElement = document.getElementById("container_"+nodeId);
	if(containerElement!=null && containerElement.style.display=="none")
	{
		_openFolder(nodeId);
	}
}
//设置树中指定节点checkbox为选中状态
Tree.prototype.changeCheck = function(nodeId)
{
	//得到节点对象，并设置其为checkbox状态

	var node = _treeNodes[eval(nodeId)];
	if(node.checked)
		_unselectNode(nodeId);
	else
		_selectNode(nodeId);
}

//设置树中指定节点checkbox为选中状态
Tree.prototype.selectCheck = function(nodeId)
{
	//得到节点对象，并设置其为checkbox状态

	var node = _treeNodes[eval(nodeId)];
	node.checked=true; 
}
//得到选中节点列表
Tree.prototype.getSelectedNodes = function()
{
	return _selectedNodes;
}
/****************************************************************/
/****************************************************************/
//树节点对象

function Node(parentNodeId,nodeId,nodeName,nodeOrder,nodeUrl)
{
 	//节点所属树对象
	this.tree = null;
	//子节点保存数组

	this.childrenNodes = new Array();
	//父节点id
	this.parentNodeId = parentNodeId;
	//节点id
	this.nodeId = nodeId;
	//节点名称
	this.nodeName = nodeName;
	//节点与兄弟节点次序

	this.nodeOrder = nodeOrder;
	//节点链接URL
	this.nodeUrl = nodeUrl;
	//节点扩展数据
	this.expandedData = "";
	//树节点保持展开状态

	this.keepExpand = false;
	//树节点checkbox状态
	this.checked = false;
}
//设置节点扩展数据
Node.prototype.setExpandedData = function(expandedData)
{
	this.expandedData = expandedData;
}
//得到节点扩展数据
Node.prototype.getExpandedData = function()
{
	return this.expandedData;
}
//节点显示方法
Node.prototype.view = function()
{
	//节点显示起点
	var htmlNode = "<div id=\"viewer_"+this.nodeId+"\">";;
	//首先显示节点缩进
	htmlNode += this.viewIndent();
	//根据是否存在子节点，做不同显示效果 
	if(this.childrenNodes.length!=0)
	{
		//存在子节点

		htmlNode += "<a href=\"#\" onClick=\"_openFolder('"+this.nodeId+"')\">";
		htmlNode += "<img id=\'folder_"+this.nodeId+"\' src=\""+Parameter.imagePath+Icon.folderclosed+"\" align=\"absmiddle\" border=\"0\"/>";
		htmlNode += "</a>"; 
		//判断是否增加checkbox 
	  	if(Parameter.requiredCheckbox==1 && this.checked==false)
	  		htmlNode += "<input id=\'checkbox_"+this.nodeId+"\' onClick=\"_selectCheckbox("+this.nodeId+")\" type=\"checkbox\" name=\""+Parameter.tagId+"\" value=\""+this.nodeId+"\"/>";
	  	if(Parameter.requiredCheckbox==1 && this.checked==true)
	  		htmlNode += "<input id=\'checkbox_"+this.nodeId+"\' onClick=\"_selectCheckbox("+this.nodeId+")\" type=\"checkbox\" name=\""+Parameter.tagId+"\" value=\""+this.nodeId+"\" checked/>";
	  	//节点响应点击打开子节点事件
	
	  	htmlNode += "<a href=\"#\" onClick=\"_openFolder('"+this.nodeId+"')\">";
	  	//显示节点文本
 		htmlNode += "<nobr>" + this.nodeName + "</nobr><br/></a>";
 		//设置子节点显示层div
 		htmlNode += "<div id=\"container_"+this.nodeId+"\" style=\"display:none;\" nowrap>";
 		//递归显示该节点子节点
 		
 		for(var i=0;i<this.childrenNodes.length;i++)
 			htmlNode += this.childrenNodes[i].view();
 		//改节点子节点显示层结束

 		htmlNode += "</div>";
 	}
	else
	{
		//叶子节点
		htmlNode += "<img src=\""+Parameter.imagePath+Icon.leaf+"\" align=\"absmiddle\" border=\"0\"/>";
		//判断是否增加checkbox
  	if(Parameter.requiredCheckbox==1 && this.checked==false)
  		htmlNode += "<input id=\'checkbox_"+this.nodeId+"\' onClick=\"_selectCheckbox("+this.nodeId+")\" type=\"checkbox\" name=\""+Parameter.tagId+"\" value=\""+this.nodeId+"\"/>";
  	if(Parameter.requiredCheckbox==1 && this.checked==true)
  		htmlNode += "<input id=\'checkbox_"+this.nodeId+"\' onClick=\"_selectCheckbox("+this.nodeId+")\" type=\"checkbox\" name=\""+Parameter.tagId+"\" value=\""+this.nodeId+"\" checked/>";
  	//叶子节点，如果引用不为空，执行引用

  	if(this.nodeUrl==null || this.nodeUrl.length==0)
  		htmlNode += "<a href=\"#\">";
  	else
  		htmlNode += "<a href=\""+this.nodeUrl+"\" target=\""+Parameter.target+"\">";
  	//显示节点文本
 		htmlNode += "<nobr>" + this.nodeName + "</nobr><br/></a>";
 	}
 	//节点显示结束
 	htmlNode += "</div>";
	//返回结果
 	return htmlNode;
}
//得到指定节点ID的根节点
Node.prototype.getRoot = function(nodeId)
{
	//得到指定ID的节点对象

	var node = _treeNodes[nodeId];
	//循环得到根节点

	while(node.parentNodeId!=null && node.parentNodeId>=0)
	{
		node = _treeNodes[node.parentNodeId];
	}
	return node;
}
//判断指定节点是否为兄弟节点的最后一个节点

Node.prototype.isLastSibling = function()
{
	//判断是否为根节点并进行处理

	if(this.parentNodeId==null || this.parentNodeId<0)
	{
		//如果与root节点列表的最后一个相重复，就为最后一个节点

		if(this.tree.rootNodes[this.tree.rootNodes.length-1]==this)
			return true;
		return false;      		
	}
	//得到该节点的父节点

	var parentNode = _treeNodes[this.parentNodeId];
	if(parentNode.childrenNodes[parentNode.childrenNodes.length-1]==this)
		return true;
	return false;
}
//节点显示时缩进控制

Node.prototype.viewIndent = function()
{
	var htmlIndent = "";
	//判断是否为根节点
 	var ir = this.parentNodeId==null || this.parentNodeId==-1;
 	//判断是否存在子节点

 	var hc = this.childrenNodes.length!=0;
 	//判断是否为兄弟节点中的最后一个节点

 	var iL = this.isLastSibling();
 	//根据各个节点的不同状态显示

 	if(hc)
 	{
 		//当前节点存在子节点

 		if(ir)
 		{
 			//当前节点存在子节点，并且是根节点
 			htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="' + Parameter.imagePath+Icon.Rplus + '" align="absmiddle"/>';
 		}
 		else
 		{
 			//当前节点存在子节点，不是根节点

 			if(iL)
 			{
 				//是最后一个非叶子节点
 				htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="' + Parameter.imagePath + Icon.plusbottom + '" align="absmiddle"/>';
 			}
 			else
 			{
 				//不是最后一个非叶子节点
 				htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="' + Parameter.imagePath + Icon.plus + '" align="absmiddle"/>';
 			}			 			
 		}
 	}
 	else
 	{
 		//当前节点不存在子节点	
 		if(ir)
 		{
 			//当前节点不存在子节点，并且是根节点

 			htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="' + Parameter.imagePath+Icon.blank + '" align="absmiddle"/>';
 		}
 		else
 		{
 			//当前节点不存在子节点，不是根节点
 			if(iL)
 			{
 				//是最后一个叶子节点

 				htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="' + Parameter.imagePath+Icon.joinbottom + '" align="absmiddle"/>';
 			}
 			else
 			{
 				//不是最后一个非叶子节点
 				htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="' + Parameter.imagePath+Icon.join + '" align="absmiddle"/>';
 			}
 		}
 	}
 	//htmlIndent += '<img id=\'pucker_'+this.nodeId+'\' border="0" src="'+ (hc ? (ir ? (Parameter.imagePath+Icon.Rminus) : (iL ? (Parameter.imagePath+Icon.plusbottom) : (Parameter.imagePath+Icon.plus))) : (ir ? (Parameter.imagePath+Icon.blank) : (iL ? (Parameter.imagePath+Icon.joinbottom) : (Parameter.imagePath+Icon.join)))) + '" align="absmiddle">';
 	//如果存在子节点，相应pucker点击时间
 	if(hc)
 	{
 		htmlIndent = '<a href="#" onClick="_openFolder(\''+this.nodeId+'\')">' + htmlIndent;
 		htmlIndent = htmlIndent + "</a>";
 	}
 	//如果当前节点为根节点,直接返回
 	if(this.parentNodeId==null || this.parentNodeId<0)
 		return htmlIndent;
 	//非根节点处理
 	var node = this;
 	while(true)
	{
		if(node.parentNodeId==null || node.parentNodeId<0)
			break;
		node = _treeNodes[node.parentNodeId];
		if(node.isLastSibling() || node.parentNodeId==null || node.parentNodeId<0)
		{
			htmlIndent = '<img src="' + Parameter.imagePath+Icon.blank + '" align="absmiddle"/>' + htmlIndent;
		}
		else
		{
			htmlIndent = '<img src="' + Parameter.imagePath+Icon.line + '" align="absmiddle"/>' + htmlIndent;
		}
	}
	//返回结果
 	return htmlIndent;			 				 	
}